<?php
App::uses('AppController', 'Controller');
/**
 * Bookings Controller
 *
 * @property Booking $Booking
 * @property PaginatorComponent $Paginator
 * @property SessionComponent $Session
 */
class BookingsController extends AppController {
    public function beforeFilter(){
        parent::beforeFilter();
        //Allow the feed and free method for all. To be used in Ajax
        $this->Auth->allow('feed', 'free');
    }
    
    public $uses = array( 'Booking', 'Room');
    
/**
 * Components
 *
 * @var array
 */
    public $components = array('Paginator', 'Session');

                
/**
 * index method
 *
 * @return void
 */
    public function index() {
        //Only meetings within the next 7 days should be displayed. 
        $this->Booking->recursive = 0;
        $nextWeek = date('Y-m-d H:i:s', time()+(7*24*60*60));
        $letzteStunde =date ('Y-m-d H:i:s', time()-(60*60));
        // $this->set('bookings', $this->Paginator->paginate());        
        $this->set('bookings', $this->Paginator->paginate(array
                    ('ende <' => $nextWeek, 'start >' => $letzteStunde))
                );
    }

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
    public function view($id = null) {
        if (!$this->Booking->exists($id)) {
                throw new NotFoundException(__('Invalid booking'));
        }
        $options = array('conditions' => array('Booking.' . $this->Booking->primaryKey => $id));
        $this->set('booking', $this->Booking->find('first', $options));
    }

/**
 * add method
 *
 * @return void
 */
	public function add() {            
		if ($this->request->is('post')) {                    
                    if ($this->booked($this->Booking->create($this->request->data))){
                        //This one is not fine if anyone is planning reoccurent Meeting in the future. This may become a problem
                        $this->Session->setFlash(__('The room you want is blocked! Alternative room?'));
                    }
                    else{
                        //The user has to be determined out of the session.
                        $this->request->data['Booking']['user_id'] = $this->Auth->user('id');
                        //Create mother event
                        $motherEvent = $this->Booking->create($this->request->data);                        
                        //Check if the booking is a repeating one. 
                        if ($this->request->data['Booking']['interval'] > 0){    
                            //wir müssen die Mutter speichern um die ID zu bekommen
                            $this->request->data['Booking']['repeated'] = $this->__writeDB($this->request->data);
                            //Es muss ein php date erstellt werden gegen das geprüft wird ob wir schon am ende der serie sind.
                            //Außerdem müssen alle Daten im php Format sein. (Werden in der Schleife wieder verwandet).
                            $start = strtotime($motherEvent['Booking']['start']);
                            $ende = strtotime($motherEvent['Booking']['ende']);
                            $bis =strtotime($this->request->data['Booking']['until']['year']
                                       .'-'.$this->request->data['Booking']['until']['month']
                                       .'-'.$this->request->data['Booking']['until']['day'].' 23:59:00');             
                            //Basierend auf Tagen
                            if ($this->request->data['Booking']['interval'] == 1 | $this->request->data['Booking']['interval'] == 7){
                                //Die intervall in Sekunden (php standart) das start und ende addiert werden muss.
                                $intervalToAdd = $this->request->data['Booking']['interval']*$this->request->data['Booking']['frequenz']*(3600*24);                                 
                                
                                //Solange start noch unter dem ende der Planung liegt loopen wir und erstellen neue Termine                                
                                while ($start < $bis){                                
                                    $start = $start+$intervalToAdd;
                                    $ende = $ende+$intervalToAdd;
                                    $this->request->data['Booking']['start'] = date( 'Y-m-d H:i:s', $start );
                                    $this->request->data['Booking']['ende'] = date( 'Y-m-d H:i:s', $ende );
                                    $this->__writeDB($this->request->data);
                                }                                
                            };
                        }
                        else{
                            //If we do not have to repeat this we simply write it
                            $this->__writeDB($this->request->data);                           
                        }  
                        return $this->redirect(array('action' => 'index'));
                    }
		}
                //$intervals = array(0 => 'Nein', 1 => 'Täglich', 7 => 'Wöchentlich', 30 => 'Monatlich', 365 => 'Jährlich');
                $intervals = array(0 => 'Nein', 1 => 'Täglich', 7 => 'Wöchentlich');
		$types = $this->Booking->Type->find('list');
		$users = $this->Booking->User->find('list');
		$rooms = $this->Booking->Room->find('list');
		$this->set(compact('types', 'users', 'rooms', 'intervals'));
	}
        
        private function __writeDB($entry){
            //This one will only save an entry. If it needs to be modified do it prior this function!
            $this->Booking->create();			
            if ($this->Booking->save($entry)) {                
                $this->Session->setFlash(__('The booking has been saved.'));  
                return $this->Booking->getLastInsertID();
            } else {
                $this->Session->setFlash(__('The booking could not be saved. Please, try again.'));
            }
        } 
                        

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
                $this->allowed($id);
		if (!$this->Booking->exists($id)) {
			throw new NotFoundException(__('Invalid booking'));
		}
		if ($this->request->is(array('post', 'put'))) {
			if ($this->Booking->save($this->request->data)) {
				$this->Session->setFlash(__('The booking has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The booking could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('Booking.' . $this->Booking->primaryKey => $id));
			$this->request->data = $this->Booking->find('first', $options);
		}
		$types = $this->Booking->Type->find('list');
		$users = $this->Booking->User->find('list');
		$rooms = $this->Booking->Room->find('list');
		$this->set(compact('types', 'users', 'rooms', 'id'));
	}

        //Löscht alle Einträge und die Mutter!
        public function deleteSeries($id = null){
            $search = $this->Booking->findById($id);            
            //Wenn wir die Mutter sind alles mit unserer id in repeated
            if ($search['Booking']['repeated'] == null){
                //Wir sind die Mutter
                $entrys = $this->Booking->findByRepeated($id);
                $first = $search;                
            } else{
                $entrys = $this->Booking->find('list', array('conditions' => array('repeated' =>$search['Booking']['repeated']), 'fields' => array('id')));
                $first = $this->Booking->findById($search['Booking']['repeated']);
            }
            //Erst alle Entrys löschen
            // -> Hier Foreach
            foreach ($entrys as  $entry){
                $this->Booking->id = $entry;
                $this->Booking->delete();
            }                     
            //dann die Mutter wenn sie nicht einzeln gelöscht wurde       
            $this->Booking->id = $first['Booking']['id'];
            if ($this->Booking->exists()){
                $this->Booking->delete();
            }
            return $this->redirect(array('action' => 'index'));
        }
        
/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
                $this->allowed($id);
		$this->Booking->id = $id;
		if (!$this->Booking->exists()) {
			throw new NotFoundException(__('Invalid booking'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->Booking->delete()) {
			$this->Session->setFlash(__('The booking has been deleted.'));
		} else {
			$this->Session->setFlash(__('The booking could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}
        
        public function calendar(){
            $rooms = $this->Room->find('all', array('fields' => array('id', 'name'), 'recursive' => 0));
            $this->set('rooms', $rooms);            
        }
        
        public function feed(){                       
            //2. Get the events corresponding to the time range and room
            if ($this->params['url']['room_id'] != 0){
                $conditions =  array('room_id' => $this->params['url']['room_id']);
            }else{
                $conditions = array();
            }
            $events = $this->Booking->find('all', array('conditions' => $conditions));
            $colors = array(
                '#000088',
                '#0000FF',
                '#008800',
                '#00FF00',                
                '#880000',
                '#FF0000',
                '#008888',
                '#0088FF',
                '#00FF88',
                '#00FFFF',
                '#880088',
                '#8800FF',
                '#888888',
            );
            //3. Create the json array
            $rows = array();
            for ($a=0; count($events)> $a; $a++) {
                //Is it an all day event?
                $all = ($events[$a]['Booking']['allday'] == 1);
                //Create an event entry
                $rows[] = array('id' => $events[$a]['Booking']['id'],
                'title' => $events[$a]['Booking']['name'],
                'start' => date('Y-m-d H:i', strtotime($events[$a]['Booking']['start'])),
                'end' => date('Y-m-d H:i',strtotime($events[$a]['Booking']['ende'])),
                'allDay' => $all,
                'backgroundColor' => $colors[$events[$a]['Booking']['room_id']]   
                );
            }             
            //4. Return as a json array
            Configure::write('debug', 0);
            $this->autoRender = false;
            $this->autoLayout = false;
            $this->header('Content-Type: application/json');
            echo json_encode($rows);            
        }
        
        private function allowed($id){
            //we have to check if this is either our case or we are an admin.
            $booking = $this->Booking->find('first', array('conditions' => array('Booking.id' => $id)));
            if (!(($booking['Booking']['user_id'] == $this->Auth->user('id')) || ($this->Session->read('isAdmin') == true))){
                $this->Session->setFlash(__('Wrong user and no admin'));
                return $this->redirect(array('action' => 'index'));
            }        
            return TRUE;
        }
        
        private function booked($test = null){
            $edge = $this->Booking->find('list', array('conditions' => array(  
                                            array(
                                                array('room_id' => $test['Booking']['room_id']),                                                                                                        
                                            ),
                                            'AND' => array(
                                                array(
                                                    'OR' => array(
                                                        array('start BETWEEN ? AND ?' =>array($test['Booking']['start'], $test['Booking']['ende'])),
                                                        array('ende BETWEEN ? AND ?' =>array($test['Booking']['start'], $test['Booking']['ende'])),
                                                    )
                                                )                                                    
                                            )
                                           )));                
            $middle = $this->Booking->find('list', array('conditions' => array(
                                                'room_id' => $test['Booking']['room_id'],
                                                'start <' => $test['Booking']['start'],
                                                'ende >' => $test['Booking']['ende']                                                                                            
                                            )));
            if ((sizeof($edge) + sizeof($middle)) > 0){
                return true;                    
            }               
            return false;
        }         
        
        public function good(){
            if ($this->request->is('post')){
                //Get a list of general matching rooms                               
                debug($this->__getFree($this->request->data['Booking']));
            }
        }
        
        private function __getFree($booking){
                //Get a list of general matching rooms                
                $possibleRooms = $this->Room->find('all', array('conditions' => array('seats >=' =>$booking['teilnehmer'])));
                //A room is available if booked of the ID is false.             
                $freeRooms = array();
                foreach ($possibleRooms as $room){
                    $raum = array();
                    $raum['Booking']['room_id'] = $room['Room']['id'];
                    $raum['Booking']['start'] = $booking['start'];
                    $raum['Booking']['ende'] = $booking['ende'];
                    if (!$this->booked($this->Booking->create($raum))){
                        array_push($freeRooms, $this->Room->findById($room['Room']['id']));
                    }                    
                }
                return $freeRooms;
        }
        
}
